package com.cw.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cw.common.constant.Constants;
import com.cw.common.constant.Response;
import com.cw.entity.SysMenu;
import com.cw.entity.SysRoleMenu;
import com.cw.entity.SysUserRole;
import com.cw.mapper.SysMenuMapper;
import com.cw.mapper.SysRoleMenuMapper;
import com.cw.mapper.SysUserRoleMapper;
import com.cw.service.ISysMenuService;
import com.cw.service.ISysRoleMenuService;
import com.cw.service.ISysRoleService;
import com.cw.util.HttpUtil;
import com.cw.util.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author smq
 * @since 2021-04-28
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
    @Autowired
    private SysMenuMapper sysMenuDao;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuDao;

    @Autowired
    private ISysRoleMenuService roleMenuService;

    @Autowired
    private SysUserRoleMapper sysUserRoleDao;

    @Override
    public List<SysMenu> getSysMenu(String menuId, String name, String code, String keepAlive,
                                    String nameLike) {

        return sysMenuDao.getSysMenu(menuId, name, code, keepAlive, nameLike);
    }

    @Override
    public int insertSysMenu(SysMenu sysMenu) {
//        sysMenu.setId(UUID.randomUUID().toString().replace("-",""));
        sysMenu.setId(UUIDUtil.uuid());
        sysMenu.setCreateTime(LocalDateTime.now());
        return sysMenuDao.insert(sysMenu);
    }

    @Override
    public int updateSysMenu(SysMenu sysMenu) {
        return sysMenuDao.updateById(sysMenu);
    }

    @Override
    public int deleteSysMenu(String menuId) {

        return sysMenuDao.deleteSysMenu(menuId);
    }

    @Override
    public int setKeepAlive(String menuId, String keepAlive) {
        return sysMenuDao.setKeepAlive(menuId, keepAlive);
    }

    @Override
    public Response getSysMenuByUserId(String userId) {
        List<SysMenu> sysMenu;
        if(Constants.admin.equals(userId)){
            //管理员登录
            sysMenu=sysMenuDao.getSysMenu(null, null, null, "0", null);
        }else{
            //非管理员登录
            sysMenu = sysMenuDao.getSysMenuByUserId(userId);
        }
        if(CollectionUtils.isEmpty(sysMenu)){
            return new Response(500,"此用户暂无权限!!!");
        }
        List<SysMenu> sysMenuTree = getChildNodes(Constants.menuParentId, sysMenu);
        return new Response(sysMenuTree);
    }

    /**
     * 获取按钮集合通过菜单主键
     * @param menuId 菜单主键
     * @return java.util.List<com.kszs.entity.SysMenu>
     * @author ly
     * @date 2020/9/23 14:46
     */
    @Override
    public Map<String,SysMenu> getButtonsByMenuId(String menuId) {
        Map<String, SysMenu> map = new HashMap<>();
        String userId = HttpUtil.getRequestHeaderInfo(Constants.USER_ID);
        List<SysMenu> sysMenus = sysMenuDao.getSysMenusByParentId(menuId);

        List<SysUserRole> sysUserRole = sysUserRoleDao.getSysUserRole(userId);

        for (SysMenu sysMenu : sysMenus) {
            for (SysUserRole userRole : sysUserRole) {
                QueryWrapper<SysRoleMenu> entityWrapper = new QueryWrapper<>();
                entityWrapper.eq("ROLE_ID", userRole.getRoleId());
                entityWrapper.eq("MENU_ID", sysMenu.getId());

                if (sysRoleMenuDao.selectCount(entityWrapper) > 0) {
                    sysMenu.setAuthority(true);
                }
            }
            //因前端需要类似于对象集合的那种数据模型,我添加的时候没有对菜单添加code后期补起来很费精力
            //就简简单单对比一下好啦! author:ly 2020-11-04
            switch (sysMenu.getName()) {
                case "查看":
                    map.put("view",sysMenu);
                    break;
                case "编辑":
                    map.put("edit",sysMenu);
                    break;
                case "新增":
                    map.put("add",sysMenu);
                    break;
                case "删除":
                    map.put("delete",sysMenu);
                    break;
                case "导出":
                    map.put("export",sysMenu);
                    break;
                default:
                    break;
            }
        }
        return map;
    }

    /**
     * 获取所有菜单
     * @return java.util.List<com.kszs.entity.SysMenu>
     * @author ly
     * @date 2020/10/10 11:52
     */
    @Override
    public List<SysMenu> getAllSysMenuTree() {
        QueryWrapper<SysMenu> entityWrapper = new QueryWrapper<>();
        entityWrapper.select("ID, NAME, PATH, ICON, COMPONENT, SORT, KEEP_ALIVE, TYPE, CREATE_TIME, DELETE_FLAG, CODE, PARENT_ID");
        List<SysMenu> sysMenus = sysMenuDao.selectList(entityWrapper);
        return Objects.requireNonNull(getChildNodes("0", sysMenus)).stream().sorted(Comparator.comparing(SysMenu::getSort)).collect(Collectors.toList());
    }

    /**
     * 获取所有菜单
     * @return java.util.List<com.kszs.entity.SysMenu>
     * @author ly
     * @date 2020/10/12 15:49
     */
    @Override
    public List<SysMenu> getAllSysMenu() {
        QueryWrapper<SysMenu> entityWrapper = new QueryWrapper<>();
        entityWrapper.select("ID,NAME,PARENT_ID,TYPE,PATH,COMPONENT");
        return sysMenuDao.selectList(entityWrapper);
    }

    /**
     * 获取按钮是否有权限通过菜单主键
     * 接口内会自己获取用户主键
     * @param menuId 菜单主键
     * @return java.util.List<com.kszs.entity.SysMenu>
     * @author ly
     * @date 2020/10/14 11:11
     */
    @Override
    public List<SysMenu> getButtonByMenuIdAndUserId(String menuId) {
        String userId = HttpUtil.getRequestHeaderInfo(Constants.USER_ID);
        //获取角色
        List<String> roleIds = roleService.getRolesByUserId(menuId);

        //获取当前菜单的子级按钮
        QueryWrapper<SysMenu> entityWrapper = new QueryWrapper<>();
        entityWrapper.eq("PARENT_ID", menuId);
        entityWrapper.eq("PARENT_ID", menuId);
        List<SysMenu> sysMenus = sysMenuDao.selectList(entityWrapper);

        QueryWrapper<SysRoleMenu> entityWrapper1 = new QueryWrapper<>();

        for (String roleId : roleIds) {
            roleMenuService.getButton(roleId,null);
        }

        entityWrapper1.eq("MENU_ID","");
        entityWrapper1.eq("","");
        return sysMenus;
    }

    /**
     * 递归遍历返回菜单树
     *
     * @param id
     * @param list
     * @return
     * @author caochun
     */
    public static List<SysMenu> getChildNodes(String id, List<SysMenu> list) {

        List<SysMenu> childList = new ArrayList<>();
        //遍历所有菜单找到所有父节点
        for (int i = 0; i < list.size(); i++) {
            if (null != list.get(i).getParentId()) {
                if (id.equals(list.get(i).getParentId())) {
                    if(!"1".equals(list.get(i).getDeleteFlag())){
                        childList.add(list.get(i));
                    }
                    //已经确定的数据删除，不在遍历
                    list.remove(i);
                    i--;
                }
            }
        }



        //判断是否有子菜单
        if (null == childList || childList.size() == 0) {
            return null;
        }else{
            childList = childList.stream().filter(menu -> menu.getSort() != null).sorted(Comparator.comparing(SysMenu::getSort)).collect(Collectors.toList());
        }

        //遍历所有父节点菜单，找到对应的子菜单
        //递归
        for (SysMenu entity : childList) {
            entity.setChildNodes(getChildNodes(entity.getId(), list));
        }
        return childList;

    }
}
